#include "game.h"
#include "stdlib.h"
#include "sdl_helper.h"

// works best if it is an even number
#define SHAKE_POWER 4

/* main menu
 * for now, it only displays a simple background image
 */
struct world_menu {
	struct world w;

	// background image and its rect
	SDL_Texture *bg;
	SDL_Rect bg_rect;
	
	SDL_Texture *buttons[3];
	SDL_Rect buttons_rect[3];

	// currently selected button
	int selected;
};

/* Initialize menu data */
void world_menu_init(struct world_menu *world) {

	// init background image and its rect
	world->bg = load_image("engine/dd_logo2.png");
	world->bg_rect.x = 0;
	world->bg_rect.y = 0;
	world->bg_rect.w = 640;
	world->bg_rect.h = 480;
	//SDL_QueryTexture(world->bg, NULL, NULL, &world->bg_rect.w, &world->bg_rect.h);

	world->buttons[0] = load_image("images/button_options.png");
	world->buttons[1] = load_image("engine/dd_logo.png");
	world->buttons[2] = load_image("images/button_close.png");

	for (int i = 0; i < 3; i++) {
		world->buttons_rect[i].x = 640 *(i+1) /4 -24;
		world->buttons_rect[i].y = i == 1 ? 480/3 : 10;
		world->buttons_rect[i].w = 48;
		world->buttons_rect[i].h = 48;
	}
	world->buttons_rect[0].x = 10;
	world->buttons_rect[0].y = 10;
	world->buttons_rect[2].x = 640 -10 -48;
	world->buttons_rect[2].y = 10;

	// default button is the middle one
	world->selected = 1;

	// init randomiser
	srand((unsigned int) time(NULL));

} // init

// update
void world_menu_update(struct world_menu *world) {

	// flag is set to change to another world
	if (world->w.next == 1) {

		// free previous world, move to the next one
		free(c_world);
		c_world = world_game_create();

		// when a new world is created, it's best to not execute much more
		return;
	}

} // update

// draw
void world_menu_draw(struct world_menu *world) {

	// background
	SDL_RenderCopy(ren, world->bg, NULL, &world->bg_rect);

	/* draw buttons
	 * the active button is drawn bigger, until I decide a better way
	 * to do it at least
	 * the rest are drawn as-is
	 */
	for (int i = 0; i < 3; i++) {
		if (i == world->selected) {
			int randx = rand() %3 == 0 ? (rand() %SHAKE_POWER) -SHAKE_POWER/2 : 0;
			int randy = rand() %3 == 0 ? (rand() %SHAKE_POWER) -SHAKE_POWER/2 : 0;
			world->buttons_rect[i].x += randx;
			world->buttons_rect[i].y += randy;
			SDL_RenderCopy(ren, world->buttons[i], NULL, &world->buttons_rect[i]);
			world->buttons_rect[i].x -= randx;
			world->buttons_rect[i].y -= randy;
		}
		else {
			SDL_RenderCopy(ren, world->buttons[i], NULL, &world->buttons_rect[i]);
		}
	}

} // draw

/* handle key input
 * when return is pressed, set flag to move to new world
 */
void world_menu_key(struct world_menu *world, SDL_Scancode key, int state) {
	switch (key) {

		// move to the previous choice
		case SDL_SCANCODE_A:
			if (state == KEY_PRESSED) {
				if (--world->selected < 0) {
					world->selected = 2;
				}
			}
			break;

		// move to the next choice
		case SDL_SCANCODE_D:
			if (state == KEY_PRESSED) {
				if (++world->selected >= 3) {
					world->selected = 0;
				}
			}
			break;

		// select the top-most button
		case SDL_SCANCODE_W:
			if (state == KEY_PRESSED) {
				world->selected = 1;
			}
			break;

		// apply choice
		case SDL_SCANCODE_RETURN:

			/* do action depending on current button
			 * 0: options
			 * 1: start game
			 * 2: exit
			 */
			switch (world->selected) {
				case 0: break;
				case 1: world->w.next =  1; break;
				case 2: world->w.next = -1; break;
			}
			break;

		default:
			break;
	}

} // key

/* mouse input not yet implemented
 */
void world_menu_mouse(struct world_menu *world,
	int button, int state, int x, int y) {
	(void) world;
	(void) button;
	(void) state;
	(void) x;
	(void) y;
}

/* responsible on initialising a new world of this type
 * and initialising any variable that needs to
 * returns a new instance of this world
 */
struct world *world_menu_create() {

	// initialise world
	struct world_menu *world = malloc(sizeof(struct world_menu));

	// set the world's callbacks to this world's
	world->w.update = (void (*)(void*)) world_menu_update;
	world->w.draw   = (void (*)(void*)) world_menu_draw;
	world->w.key    = (void (*)(void*, SDL_Scancode, int)) world_menu_key;
	world->w.mouse  = (void (*)(void*, int, int, int, int)) world_menu_mouse;
	world->w.next = 0;

	// init
	world_menu_init(world);

	// return the instance of this world
	return (struct world*) world;
}
